#ifndef SPL_DIALOG
#define SPL_DIALOG

//! Class to manage dialogs
class DLLEXPORT Dialog : public FrameWnd
{
private:
  //! Dialog is inside dialog procedure
  BOOL      m_fRecursing;
  //! Dialog is modal (locking other windows)
  BOOL      fModal;

  //! Default dialog procedure
  static INT_PTR CALLBACK defDlgProc(HWND, UINT, WPARAM, LPARAM);

protected:
  //! Window procedure
  virtual VOID    wndProc(Event::WndProcEvent& iEvent);

  //! Occurs before the creation of a dialog
  //! Returns:     true to give the focus to hWndControl, otherwise false
  virtual VOID    onInitDialog(Event::InitDialogEvent& iEvent);

public:
  //! Dialog constructor
  SPLINL Dialog() {}
  //! Dialog destructor
  SPLINL virtual ~Dialog() { destroy(); };

  //! Creates dialog
  //! pszTemplate:        dialog template name
  //! hInstance:          dialog template instance handle
  //! hwndParent:         parent window handle (can be null)
  SPLINL BOOL create(
    LPCTSTR     pszTemplate,
    HINSTANCE   hInstance,
    HWND        hwndParent = NULL)
  {
    m_fRecursing = FALSE;
    fModal = FALSE;

    return CreateDialogParam(
      hInstance,
      pszTemplate,
      hwndParent,
      defDlgProc,
      (LPARAM)this
      ) > 0;
  }

  //! Creates dialog
  //! pszTemplate:        dialog template name
  //! hwndParent:         parent window handle (can be null)
  SPLINL BOOL create(
    LPCTSTR     pszTemplate,
    HWND        hwndParent = NULL)
  {
    m_fRecursing = FALSE;
    fModal = FALSE;

    return CreateDialogParam(
      GetModuleHandle(NULL),
      pszTemplate,
      hwndParent,
      defDlgProc,
      (LPARAM)this
      ) > 0;
  }

  //! Creates modal dialog and enters message loop
  //! pszTemplate:        dialog template name
  //! hInstance:          dialog template instance handle
  //! hwndParent:         parent window handle (can be null)
  SPLINL WPARAM createModal(
    LPCTSTR     pszTemplate,
    HINSTANCE   hInstance,
    HWND        hwndParent = NULL)
  {
    m_fRecursing = FALSE;
    fModal = TRUE;

    return DialogBoxParam(
      hInstance,
      pszTemplate,
      hwndParent,
      defDlgProc,
      (LPARAM)this
      ) > 0;
  }

  //! Creates modal dialog and enters message loop
  //! pszTemplate:        dialog template name
  //! hwndParent:         parent window handle (can be null)
  SPLINL WPARAM createModal(
    LPCTSTR     pszTemplate,
    HWND        hwndParent = NULL)
  {
    m_fRecursing = FALSE;
    fModal = TRUE;

    return DialogBoxParam(
      GetModuleHandle(NULL),
      pszTemplate,
      hwndParent,
      defDlgProc,
      (LPARAM)this
      ) > 0;
  }

  //! Creates modeless dialog and enters message loop
  //! pszTemplate:        dialog template name
  //! hInstance:          dialog template instance handle
  //! hwndParent:         parent window handle (can be null)
  SPLINL WPARAM createModeless(
    LPCTSTR     pszTemplate,
    HINSTANCE   hInstance,
    HWND        hwndParent = NULL)
  {
    m_fRecursing = FALSE;
    fModal = FALSE;

    return create(pszTemplate, hInstance, hwndParent) ? run(TRUE) : FALSE;
  }

  //! Creates modeless dialog and enters message loop
  //! pszTemplate:        dialog template name
  //! hwndParent:         parent window handle (can be null)
  SPLINL WPARAM createModeless(
    LPCTSTR     pszTemplate,
    HWND        hwndParent = NULL)
  {
    m_fRecursing = FALSE;
    fModal = FALSE;

    return create(pszTemplate, hwndParent) ? run(TRUE) : FALSE;
  }

  //! Returns TRUE if previously created dialog was modal
  SPLINL BOOL isModal()
  {
    return fModal;
  }

  //! Destroyes dialog
  LRESULT destroy();
};

#endif